package com.zhijian.medical.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.zhijian.medical.dao.local.RoutinePatientDiagnoseExtendMapper;
import com.zhijian.medical.dao.local.RoutinePatientDiagnoseHzMapper;
import com.zhijian.medical.dao.local.RoutinePatientDiagnoseMapper;
import com.zhijian.medical.dao.local.RoutineQcMapper;
import com.zhijian.medical.entity.dto.PersonDto;
import com.zhijian.medical.entity.po.*;
import com.zhijian.medical.entity.vo.request.*;
import com.zhijian.medical.entity.vo.response.*;
import com.zhijian.medical.enums.RoutineHistoryEnum;
import com.zhijian.medical.enums.RoutinePathologySampleStepEnum;
import com.zhijian.medical.enums.RoutinePatientDiagnoseEnum;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.impl.SpecialInstructionServiceImpl;
import com.zhijian.util.AssertUtil;
import com.zhijian.util.page.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class RoutinePatientDiagnoseService {

    @Autowired
    RoutinePatientDiagnoseMapper routinePatientDiagnoseMapper;

    @Autowired
    RoutinePatientService routinePatientService;

    @Autowired
    RoutinePatientDiagnoseCollectService routinePatientDiagnoseCollectService;

    @Autowired
    RoutinePatientDiagnoseLatestService routinePatientDiagnoseLatestService;

    @Autowired
    RoutinePatientDiagnoseExtendMapper routinePatientDiagnoseExtendMapper;

    @Autowired
    RoutinePatientDiagnoseHzMapper routinePatientDiagnoseHzMapper;

    @Autowired
    RoutineSampleService sampleService;

    @Autowired
    private RoutineStepRecordService stepRecordService;

    @Autowired
    private RoutineStepService stepService;

    @Autowired
    private RoutineQcMapper routineQcMapper;

    @Autowired
    private RoutineSingleSampleService singleSampleService;

    @Autowired
    private TechInstructionService techInstructionService;

    @Autowired
    private SpecialInstructionServiceImpl specialInstructionService;

    /**
     * 查询病人的诊断结果
     * @param searchVo 查询条件
     * @return 诊断信息
     */
    public Page<RoutinePatientVo> selectPage(RoutinePatientSearchVo searchVo){
        int pageNum = searchVo.getPageNum() != null ? searchVo.getPageNum() : 1;
        int pageSize = searchVo.getPageSize() != null ? searchVo.getPageSize() : 50;
        PageHelper.startPage(pageNum, pageSize);
        com.github.pagehelper.Page<RoutinePatientVo> orgData = routinePatientDiagnoseMapper.selectPage(searchVo);
        List<RoutinePatientVo> dataListOrg = orgData.getResult();
        for (RoutinePatientVo routinePatientVo : dataListOrg){
            if (routinePatientVo.getPaperState() == null){
                routinePatientVo.setPaperState(0);
            }
            addSubModule(routinePatientVo);
        }
        Page<RoutinePatientVo> dataList =
                new com.zhijian.util.page.Page<>(true, Integer.parseInt( String.valueOf(orgData.getTotal())), pageNum, pageSize);
        dataList.setData(dataListOrg);
        return dataList;
    }

    /**
     * 补充子集模块
     * @param routinePatientVo 诊断列表
     */
    private void addSubModule(RoutinePatientVo routinePatientVo){
        QueryWrapper<RoutinePatientDiagnose> routinePatientDiagnoseQueryWrapper = new QueryWrapper<>();
        routinePatientDiagnoseQueryWrapper.eq("patient_id", routinePatientVo.getId());
        RoutinePatientDiagnose routinePatientDiagnose = routinePatientDiagnoseMapper.selectOne(routinePatientDiagnoseQueryWrapper);
        if (routinePatientDiagnose == null){
            routinePatientDiagnose = new RoutinePatientDiagnose();
            routinePatientDiagnose.setPatientId(routinePatientVo.getId());
            routinePatientDiagnose.setCreateTime(new Date());
            routinePatientDiagnose.setUpdateTime(new Date());
            routinePatientDiagnose.setRysj(routinePatientVo.getRysj());
            routinePatientDiagnoseMapper.insert(routinePatientDiagnose);
        }
        QueryWrapper<RoutinePatientDiagnoseExtend> queryExtend = new QueryWrapper<>();
        queryExtend.eq("diagnose_id", routinePatientDiagnose.getId());
        RoutinePatientDiagnoseExtend extendData = routinePatientDiagnoseExtendMapper.selectOne(queryExtend);
        if (extendData == null){
            extendData = new RoutinePatientDiagnoseExtend();
            extendData.setDiagnoseId(routinePatientDiagnose.getId());
            extendData.setCreateTime(new Date());
            extendData.setUpdateTime(new Date());
            routinePatientDiagnoseExtendMapper.insert(extendData);
        }
        QueryWrapper<RoutinePatientDiagnoseHz> queryHz = new QueryWrapper<>();
        queryHz.eq("diagnose_id", routinePatientDiagnose.getId());
        RoutinePatientDiagnoseHz hz = routinePatientDiagnoseHzMapper.selectOne(queryHz);
        if (hz == null){
            hz = new RoutinePatientDiagnoseHz();
            hz.setDiagnoseId(routinePatientDiagnose.getId());
            hz.setCreateTime(new Date());
            hz.setUpdateTime(new Date());
            routinePatientDiagnoseHzMapper.insert(hz);
        }
    }

    /**
     * 最近查看
     * @return
     */
    public Page<RoutinePatientVo> selectLatestPage(RoutinePatientSearchVo searchVo){
        int pageNum = 1;
        int pageSize = 20;
        PageHelper.startPage(pageNum, pageSize);
        com.github.pagehelper.Page<RoutinePatientVo> orgData = routinePatientDiagnoseMapper.selectLatestPage(searchVo);
        List<RoutinePatientVo> dataListOrg = orgData.getResult();
        for (RoutinePatientVo routinePatientVo : dataListOrg){
            if (routinePatientVo.getPaperState() == null){
                routinePatientVo.setPaperState(0);
            }
        }
        Page<RoutinePatientVo> dataList =
                new com.zhijian.util.page.Page<>(true, Integer.parseInt( String.valueOf(orgData.getTotal())), pageNum, pageSize);
        dataList.setData(dataListOrg);
        return dataList;
    }

    public RoutinePatientDiagnoseVo selectOne(String blhNo){
        RoutinePatientDiagnoseVo data = routinePatientDiagnoseMapper.selectOneByBlh(blhNo);
        if (data == null || data.getId() == null){
            RoutinePatientVo routinePatient = routinePatientService.selectOne(RoutinePatientSearchVo.builder().conventionPathologyNumber(blhNo).build());
            RoutinePatientDiagnose add = new RoutinePatientDiagnose();
            add.setPatientId(routinePatient.getId());
            if (data != null){
                add.setRysj(data.getQcRysj());
            }
            addDiagnose(add);
        }
        List<RoutineSampleVo> routineSampleVos = sampleService.selectList(RoutineSampleSearchVo.builder().conventionPathologyNumber(blhNo).build());
        // 病理样本信息
        List<RoutineQcSampleVo> qcSampleVos = new ArrayList<>();
        for (RoutineSampleVo sampleVo: routineSampleVos) {
            RoutineQcSampleVo qcSampleVo = new RoutineQcSampleVo();
            BeanUtils.copyProperties(sampleVo, qcSampleVo);
            qcSampleVo.setFixedTime(sampleVo.getOffBodyTime());
            qcSampleVos.add(qcSampleVo);
        }
        if (data != null){
            data.setQcSampleVos(qcSampleVos);
            data.setStepVo(stepService.selectOne(RoutineStepSearchVo.builder()
                    .conventionPathologyNumber(blhNo)
                    .build()));

            data.setTechInstructionNum(techInstructionService.count(TechInstructionSearchVo.builder()
                    .diagnoseId(data.getId())
                    .status((byte)0)
                    .build()));

            data.setSpecialInstructionNum(specialInstructionService.count(SpecialInstructionSearchVo.builder()
                    .diagnoseId(data.getId())
                    .status((byte)0)
                    .build()));
        }
        return data;
    }

    public RoutinePatientDiagnose addDiagnose(RoutinePatientDiagnose routinePatientDiagnose){
        AssertUtil.check(routinePatientDiagnose.getPatientId() == null, "病人ID不能为空！");
        QueryWrapper<RoutinePatientDiagnose> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("patient_id", routinePatientDiagnose.getPatientId());
        RoutinePatientDiagnose one = routinePatientDiagnoseMapper.selectOne(queryWrapper);
        RoutinePatient routinePatient = routinePatientService.selectById(routinePatientDiagnose.getPatientId());
        if (one != null){
            routinePatientDiagnose.setId(one.getId());
            updateDiagnose(routinePatientDiagnose);
        }else {
            Date now = new Date();
            routinePatientDiagnose.setCreateTime(now);
            routinePatientDiagnose.setUpdateTime(now);
            routinePatientDiagnoseMapper.insert(routinePatientDiagnose);
        }
        routinePatientDiagnose.setConventionPathologyNumber(routinePatient.getConventionPathologyNumber());
        return routinePatientDiagnose;
    }

    public RoutinePatientDiagnoseVo selectOneById(Long diagnoseId){
        return routinePatientDiagnoseMapper.selectOneById(diagnoseId);
    }
    /**
     * 最近查询
     * @param patientId 病人ID
     */
    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    public void updateLatestTime(Long patientId){
        QueryWrapper<RoutinePatientDiagnose> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("patient_id", patientId);
        RoutinePatientDiagnose one = routinePatientDiagnoseMapper.selectOne(queryWrapper);
        Date now = new Date();
        if (one != null){
            RoutinePatientDiagnose upd = new RoutinePatientDiagnose();
            upd.setId(one.getId());
            upd.setLatestTime(now);
            routinePatientDiagnoseMapper.updateById(upd);
        }else {
            RoutinePatient routinePatient = routinePatientService.selectById(patientId);
            Integer hisCount = stepRecordService.count(RoutineStepRecordSearchVo.builder()
                    .step(RoutineHistoryEnum.ZD.getCode().byteValue())
                    .conventionPathologyNumber(routinePatient.getConventionPathologyNumber())
                    .build());
            if (hisCount < 1) {
                // 修改状态 + 增加状态记录
                String contetnt = "在科室诊断";
                stepService.updateStepByNums(routinePatient.getConventionPathologyNumber(), contetnt, RoutinePathologySampleStepEnum.ZD.getCode().byteValue());
                stepRecordService.insert(RoutineStepRecord.builder()
                        .conventionPathologyNumber(routinePatient.getConventionPathologyNumber())
                        .step(RoutinePathologySampleStepEnum.ZD.getCode().byteValue())
                        .content(contetnt)
                        .build());
            }
            //初始化诊断内容
            RoutinePatientDiagnose add = new RoutinePatientDiagnose();
            add.setPatientId(patientId);
            add.setCreateTime(now);
            add.setUpdateTime(now);
            add.setPaperState(0);
            routinePatientDiagnoseMapper.insert(add);
        }
        routinePatientDiagnoseLatestService.handlePatient(patientId);
    }

    public void updateDiagnose(RoutinePatientDiagnose routinePatientDiagnose){
        Date now = new Date();
        routinePatientDiagnose.setUpdateTime(now);
        adjustPaperState(routinePatientDiagnose);
        routinePatientDiagnoseMapper.updateById(routinePatientDiagnose);
    }

    public void auditDiagnose(Long diagnoseId){
        RoutinePatientDiagnose routinePatientDiagnose = routinePatientDiagnoseMapper.selectById(diagnoseId);
        Date now = new Date();
        RoutinePatientDiagnose upd = auditPaperState(routinePatientDiagnose, null);
        upd.setUpdateTime(now);
        upd.setId(routinePatientDiagnose.getId());
        routinePatientDiagnoseMapper.updateById(upd);
    }

    public void auditDiagnose(Long diagnoseId, Long auditUserId){
        RoutinePatientDiagnose routinePatientDiagnose = routinePatientDiagnoseMapper.selectById(diagnoseId);
        Date now = new Date();
//        RoutinePatientDiagnose upd = auditPaperState(routinePatientDiagnose, auditUserId);
        // 审核-设置复诊医生
        RoutinePatientDiagnose upd = new RoutinePatientDiagnose();
        PersonDto user = CurrentUserHolder.getUser();
        upd.setFollowDocker(user.getId());
        upd.setFollowDockerName(user.getName());

        if (auditUserId == null){
            upd.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.CENSOR.getCode());
        }else {
            upd.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.FOLLOW_ING.getCode());
        }
        upd.setUpdateTime(now);
        upd.setId(routinePatientDiagnose.getId());
        routinePatientDiagnoseMapper.updateById(upd);
    }

    /**
     * 调整诊断状态
     */
    private void adjustPaperState(RoutinePatientDiagnose routinePatientDiagnose){
        PersonDto user = CurrentUserHolder.getUser();
        if (routinePatientDiagnose.getPaperState() == null ) {
            routinePatientDiagnose.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.DGS_ING.getCode());
        } else if (RoutinePatientDiagnoseEnum.DiagnoseEnum.DGS_ING.getCode().equals(routinePatientDiagnose.getPaperState())){
            routinePatientDiagnose.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.FOLLOW.getCode());
            routinePatientDiagnose.setFirstDocker(user.getId());
            routinePatientDiagnose.setFirstDockerName(user.getName());
        }else if (RoutinePatientDiagnoseEnum.DiagnoseEnum.FOLLOW.getCode().equals(routinePatientDiagnose.getPaperState())){
            routinePatientDiagnose.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.FOLLOW_ING.getCode());
            routinePatientDiagnose.setFollowDocker(user.getId());
            routinePatientDiagnose.setFollowDockerName(user.getName());
        }
    }

    /**
     * 审核当前报告
     * @param routinePatientDiagnose 报告对象
     */
    private RoutinePatientDiagnose auditPaperState(RoutinePatientDiagnose routinePatientDiagnose, Long auditUserId){
        RoutinePatientDiagnose upd = new RoutinePatientDiagnose();
        PersonDto user = CurrentUserHolder.getUser();
//        if (routinePatientDiagnose.getFirstDocker() == null){
//            upd.setFirstDocker(user.getId());
//            upd.setFirstDockerName(user.getName());
//        }
//        if (routinePatientDiagnose.getFollowDocker() == null){
//            upd.setFollowDocker(user.getId());
//            upd.setFollowDockerName(user.getName());
//        }
        if (auditUserId == null){
            upd.setCensorDocker(user.getId());
            upd.setCensorDockerName(user.getName());
            upd.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.CENSOR.getCode());
        }else {
            upd.setPaperState(RoutinePatientDiagnoseEnum.DiagnoseEnum.FOLLOW_ING.getCode());
            upd.setCensorDocker(auditUserId);
        }
        return upd;
    }

    public RoutinePatientDiagnose.DiseaseCollect addCollect(RoutinePatientDiagnose.DiseaseCollect diseaseCollect){
        RoutinePatientDiagnoseCollect routinePatientDiagnoseCollect = new RoutinePatientDiagnoseCollect();
        routinePatientDiagnoseCollect.setDiseaseId(diseaseCollect.getDiseaseId());
        routinePatientDiagnoseCollect.setTypeId(diseaseCollect.getDiagnoseId());
        routinePatientDiagnoseCollect.setCollectName(diseaseCollect.getDiseaseName());
        routinePatientDiagnoseCollect.setType(RoutinePatientDiagnoseEnum.DiagnoseCollectEnum.DISEASE.getCode());
        routinePatientDiagnoseCollectService.addCollect(routinePatientDiagnoseCollect);
        return diseaseCollect;
    }

    public RoutinePatientDiagnoseVo.StatisticsInfo statics(RoutinePatientSearchVo routinePatientSearchVo){
        RoutinePatientDiagnoseVo.StatisticsInfo statisticsInfo = new RoutinePatientDiagnoseVo.StatisticsInfo();
        Integer auditCount = routinePatientDiagnoseMapper.auditDoingCount(routinePatientSearchVo);
        Integer collectCount = routinePatientDiagnoseMapper.collectCount(routinePatientSearchVo);
        statisticsInfo.setAuditDoing(auditCount);
        statisticsInfo.setCollectNum(collectCount);
        return statisticsInfo;
    }

    public Page<RoutineSingleSampleVo> readSingleSampleList(RoutinePatientSearchVo routinePatientSearchVo){
        RoutineQcVo routineQcVo = routineQcMapper.selectOne(RoutineQcSearchVo.builder().
                conventionPathologyNumber(routinePatientSearchVo.getConventionPathologyNumber()).build());
        RoutineSingleSampleSearchVo searchVo = RoutineSingleSampleSearchVo.builder()
                .qcId(routineQcVo.getId())
                .build();
        searchVo.setPageNum(routinePatientSearchVo.getPageNum());
        searchVo.setPageSize(routinePatientSearchVo.getPageSize());
        Page<RoutineSingleSampleVo> routineSingleSampleVoPage = singleSampleService.selectPage(searchVo);
        List<RoutineSingleSampleVo> routineSingleSampleVoList = routineSingleSampleVoPage.getData();
        for (RoutineSingleSampleVo singleSampleVo : routineSingleSampleVoList){
            if (StringUtils.hasText(singleSampleVo.getNumber()) && singleSampleVo.getNumber().contains("-")){
                String[] numberArr = singleSampleVo.getNumber().split("-");
                singleSampleVo.setNumber(numberArr[1]);
            }
        }
        return routineSingleSampleVoPage;
    }
}
